home *** CD-ROM | disk | FTP | other *** search
- {$F+,R-}
- unit Eyes;
- interface
-
- uses graph,mouse;
-
- type EyeDataRec = record
- BColor : byte; {eye background color}
- EColor : byte; {eye rim color}
- PColor : byte; {pupil color}
- Style : integer; {eye style}
- Xasp : word; {screen X aspect}
- Yasp : word; {screen Y aspect}
-
- Exr : integer; {Eyeball X range}
- Eyr : integer; {Eyeball Y range}
- Bpsx : integer; {Pupil X size}
- Bpsy : integer; {Pupil Y size}
-
- Lesx : integer; {Left eyeball X start pos}
- Lesy : integer; {Left eyeball Y start pos}
- Lecx : integer; {Left eyeball X center pos}
- Lecy : integer; {Left eyeball Y center pos}
- Leex : integer; {Left eyeball X end pos}
- Leey : integer; {Left eyeball Y end pos}
-
- Resx : integer; {Right eyeball X start pos}
- Resy : integer; {Right eyeball Y start pos}
- Recx : integer; {Right eyeball X center pos}
- Recy : integer; {Right eyeball Y center pos}
- Reex : integer; {Right eyeball X end pos}
- Reey : integer; {Right eyeball Y end pos}
-
- Pexl : integer; {Left eye X Position}
- Peyl : integer; {Left eye Y Position}
- Pexr : integer; {Right eye X Position}
- Peyr : integer; {Right eye Y Position}
- TPexl : integer; {Temp Left eye X Position}
- TPeyl : integer; {Temp Left eye Y Position}
- TPexr : integer; {Temp Right eye X Position}
- TPeyr : integer; {Temp Right eye Y Position}
-
- end;
-
-
- procedure MakeEyes(var EyeData:EyeDataRec;
- Xp,Yp,Size,How:integer; Eye,Edge,Pupil:byte);
- procedure LookAt(var EyeData:EyeDataRec; Xp,Yp:integer);
-
-
- implementation
-
- {----------------------------------------------------}
- {rounding divide. divides m into d and rounds up result}
- function rdiv(d:longint; m:word):word;
- Inline(
- $5B { pop bx}
- /$58 { pop ax}
- /$5A { pop dx}
- /$F7/$F3 { div bx}
- /$01/$D2 { add dx,dx}
- /$39/$D3 { cmp bx,dx}
- /$73/$01 { jnc nornd}
- /$40 { inc ax}
- ); {nornd:}
-
-
- {----------------------------------------------------}
- function Limit(Value,Start,Stop:integer):integer;
- Inline(
- $58 { pop ax ;Stop}
- /$5B { pop bx ;Start}
- /$59 { pop cx ;Value}
- /$39/$C1 { cmp cx,ax}
- /$7F/$08 { JG done}
- /$89/$D8 { mov ax,bx}
- /$39/$C1 { cmp cx,ax}
- /$7C/$02 { JL done}
- /$89/$C8 { mov ax,cx}
- ); {done:}
-
- {----------------------------------------------------}
- {compute an integer based log2}
- {$F+} function ILog2(Value:longint):word; external;
- {$L INTLOG2}
-
-
- {----------------------------------------------------}
- {put the eyes on the screen in the location specified}
- procedure MakeEyes(var EyeData:EyeDataRec;
- Xp,Yp,Size,How:integer; Eye,Edge,Pupil:byte);
- begin
- with EyeData do
- begin
- Style := How; {store away pattern info}
- BColor := Eye; {and the colors}
- EColor := Edge;
- PColor := Pupil;
-
- GetAspectRatio(Xasp,Yasp); {compute graphics eye X/Y size}
- Eyr := (Xasp*Size*2)div Yasp; {adjusted for screen aspect ratio}
- Exr := Size;
-
- Lecx := Xp;
- Lesx := Lecx-(Exr div 2); {compute left eye parameters}
- Leex := Lesx+Exr;
- Lecy := Yp;
- Lesy := Lecy-(Eyr div 2);
- Leey := Lesy+Eyr;
-
- Recx := Xp+(Exr*3); {compute right eye parameters}
- Resx := Recx-(Exr div 2);
- Reex := Resx+Exr;
- Recy := Yp;
- Resy := Recy-(Eyr div 2);
- Reey := Resy+Eyr;
-
- Bpsx := Exr div 5; {compute pupil X/Y size}
- Bpsy := Eyr div 5;
-
- Pexl := Lecx; {default pupil start to center of eye}
- Peyl := Lecy;
- Pexr := Recx;
- Peyr := Recy;
-
- HideMouse; {hide the mouse while we do this}
- SetFillStyle(SolidFill,BColor); {draw the eyes on the screen}
- SetColor(EColor);
- FillEllipse(Pexl,Peyl,Exr,Eyr);
- FillEllipse(Pexr,Peyr,Exr,Eyr);
-
- { Rectangle(Lesx,Lesy,Leex,Leey); } {show pupil work area}
- { Rectangle(Resx,Resy,Reex,Reey); } { (for debugging) }
-
- SetFillStyle(Solidfill,PColor); {now draw the pupils }
- SetColor(PColor); {(Orphan Anney we ain't!)}
- FillEllipse(Pexl,Peyl,Bpsx,Bpsy);
- FillEllipse(Pexr,Peyr,Bpsx,Bpsy);
- ShowMouse; {all done, so let 'em have the mouse back}
- end;
- end;
-
-
- {----------------------------------------------------}
- {compute where the pupil is placed within the eye}
- function Map(Style,Start,Center,Stop,Max:integer; Pos:longint):integer;
- begin
- case Style of
- 1: begin
- if Pos-Center > 0 then {compute scaled pupil X location}
- Map := Center+rdiv((Stop-Center)*4,rdiv((Max-Center)*4,Pos-Center))
- else if Pos-Center < 0 then
- Map := Center-rdiv((Center-Start)*4,rdiv(Center*4,abs(Pos-Center)))
- else Map := Center;
- end;
- 2: begin
- if (Pos-Center) > 0 then {compute log2 pupil X location}
- begin
- Map := Center+rdiv(longint(ILog2(Pos-Center))*4,
- rdiv(longint(ILog2(Max-Center))*4,Stop-Center));
- end
- else if (Pos-Center) < 0 then
- begin
- Map := Center-rdiv(longint(ILog2(abs(Pos-Center)))*4,
- rdiv(longint(ILog2(Center))*4,Center-Start));
- end
- else Map := Center;
- end;
- else Map := Limit(integer(Pos),Start,Stop); {compute clipped X location}
- end; {case}
- end;
-
-
-
- {----------------------------------------------------}
- {point the pupils at the indicated screen location}
- procedure LookAt(var EyeData:EyeDataRec; Xp,Yp:integer);
- begin
- with EyeData do
- begin
- TPexl := Map(Style,Lesx,Lecx,Leex,GetMaxX,Xp);
- TPeyl := Map(Style,Lesy,Lecy,Leey,GetMaxY,Yp);
- TPexr := Map(Style,Resx,Recx,Reex,GetMaxX,Xp);
- TPeyr := Map(Style,Resy,Recy,Reey,GetMaxY,Yp);
-
- {if the pupil location changed update the pupils}
- if (TPexl<>Pexl) or (TPeyl<>Peyl) or (TPexr<>Pexr) or (TPeyr<>Peyr) then
- begin
- HideMouse;
- SetFillStyle(SolidFill,BColor); {restore eye background}
- SetColor(BColor);
- FillEllipse(Pexl,Peyl,Bpsx,Bpsy);
- FillEllipse(Pexr,Peyr,Bpsx,Bpsy);
- Pexl := TPexl;
- Peyl := TPeyl;
- Pexr := TPexr;
- Peyr := TPeyr;
- SetFillStyle(Solidfill,PColor); {draw new pupil}
- SetColor(PColor);
- FillEllipse(Pexl,Peyl,Bpsx,Bpsy);
- FillEllipse(Pexr,Peyr,Bpsx,Bpsy);
- ShowMouse;
- end;
- end;
- end;
-
-
- {----------------------------------------------------}
- {no initialization}
- end.
-